/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* --- Web: www.STCMCUDATA.com  ---------------------------------------*/
/* --- QQ:  800003751 -------------------------------------------------*/
/* ���Ҫ�ڳ�����ʹ�ô˴���,���ڳ�����ע��ʹ����STC�����ϼ�����            */
/*---------------------------------------------------------------------*/

#include	"STC8G_H_I2C.h"

u8 __xdata I2C_Buffer[I2C_BUF_LENTH];
//u8 xdata *I2C_Buffer;

#define SLAW    0xA2
#define SLAR    0xA3

//========================================================================
// ����: void	I2C_Init(I2C_InitTypeDef *I2Cx)
// ����: I2C��ʼ������.
// ����: I2Cx: �ṹ����,��ο�I2C.h��Ķ���.
// ����: none.
// �汾: V1.0, 2012-11-22
//========================================================================
void	I2C_Init(I2C_InitTypeDef *I2Cx)
{
	EAXSFR();		/* MOVX A,@DPTR/MOVX @DPTR,Aָ��Ĳ�������Ϊ��չSFR(XSFR) */
	
	if(I2Cx->I2C_Mode == I2C_Mode_Master)
	{
		I2C_Master();			//��Ϊ����	
		I2CMSST = 0x00;		//���I2C����״̬�Ĵ���
		I2C_SetSpeed(I2Cx->I2C_Speed);
		if(I2Cx->I2C_MS_WDTA == ENABLE)		I2C_WDTA_EN();	//ʹ���Զ�����
		else									I2C_WDTA_DIS();	//��ֹ�Զ�����
	}
	else
	{
		I2C_Slave();	//��Ϊ�ӻ�
		I2CSLST = 0x00;		//���I2C�ӻ�״̬�Ĵ���
		I2C_Address(I2Cx->I2C_SL_ADR);
		if(I2Cx->I2C_SL_MA == ENABLE)		I2C_MATCH_EN();	//�ӻ���ַ�ȽϹ��ܣ�ֻ������ƥ���ַ
		else									I2C_MATCH_DIS();	//��ֹ�ӻ���ַ�ȽϹ��ܣ����������豸��ַ
	}
	
	I2C_Function(I2Cx->I2C_Enable);
	
//	if(I2C_Buffer){free(I2C_Buffer);I2C_Buffer = NULL;}	//free memory
//	I2C_Buffer = (u8*)malloc(sizeof(u8)*I2C_BUF_LENTH);

	EAXRAM();		/* MOVX A,@DPTR/MOVX @DPTR,Aָ��Ĳ�������Ϊ��չRAM(XRAM) */
}

//========================================================================
// ����: void	Wait (void)
// ����: �ȴ�����ģʽI2C������ִ�����I2CMSCR.
// ����: mode: ָ��ģʽ, ȡֵ I2C_Mode_Master �� I2C_Mode_Slave.
// ����: none.
// �汾: V1.0, 2012-11-22
//========================================================================
void Wait()
{
	while (!(I2CMSST & 0x40));
	I2CMSST &= ~0x40;
}

//========================================================================
// ����: void Start (void)
// ����: I2C������ʼ����.
// ����: none.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void Start()
{
	I2CMSCR = 0x01;                         //����START����
	Wait();
}

//========================================================================
// ����: void SendData (char dat)
// ����: I2C����һ���ֽ����ݺ���.
// ����: ���͵�����.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void SendData(char dat)
{
	I2CTXD = dat;                           //д���ݵ����ݻ�����
	I2CMSCR = 0x02;                         //����SEND����
	Wait();
}

//========================================================================
// ����: void RecvACK (void)
// ����: I2C��ȡACK����.
// ����: none.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void RecvACK()
{
	I2CMSCR = 0x03;                         //���Ͷ�ACK����
	Wait();
}

//========================================================================
// ����: char RecvData (void)
// ����: I2C��ȡһ���ֽ����ݺ���.
// ����: none.
// ����: ��ȡ����.
// �汾: V1.0, 2020-09-15
//========================================================================
char RecvData()
{
	I2CMSCR = 0x04;                         //����RECV����
	Wait();
	return I2CRXD;
}

//========================================================================
// ����: void SendACK (void)
// ����: I2C����ACK����.
// ����: none.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void SendACK()
{
	I2CMSST = 0x00;                         //����ACK�ź�
	I2CMSCR = 0x05;                         //����ACK����
	Wait();
}

//========================================================================
// ����: void SendNAK (void)
// ����: I2C����NAK����.
// ����: none.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void SendNAK()
{
	I2CMSST = 0x01;                         //����NAK�ź�
	I2CMSCR = 0x05;                         //����ACK����
	Wait();
}

//========================================================================
// ����: void Stop (void)
// ����: I2C����ֹͣ����.
// ����: none.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void Stop()
{
	I2CMSCR = 0x06;                         //����STOP����
	Wait();
}

//========================================================================
// ����: void	I2C_WriteNbyte(u8 addr, u8 *p, u8 number)
// ����: I2Cд�����ݺ���.
// ����: addr: ָ����ַ, *pд�����ݴ洢λ��, numberд�����ݸ���.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void I2C_WriteNbyte(u8 addr, u8 *p, u8 number)  /*  WordAddress,First Data Address,Byte lenth   */
{
	EAXSFR();		/* MOVX A,@DPTR/MOVX @DPTR,Aָ��Ĳ�������Ϊ��չSFR(XSFR) */
	Start();                                //������ʼ����
	SendData(SLAW);                         //�����豸��ַ+д����
	RecvACK();
	SendData(addr);                         //���ʹ洢��ַ
	RecvACK();
	do
	{
		SendData(*p++);
		RecvACK();
	}
	while(--number);
	Stop();                                 //����ֹͣ����
	EAXRAM();		/* MOVX A,@DPTR/MOVX @DPTR,Aָ��Ĳ�������Ϊ��չRAM(XRAM) */
}

//========================================================================
// ����: void	I2C_ReadNbyte(u8 addr, u8 *p, u8 number)
// ����: I2C��ȡ���ݺ���.
// ����: addr: ָ����ַ, *p��ȡ���ݴ洢λ��, number��ȡ���ݸ���.
// ����: none.
// �汾: V1.0, 2020-09-15
//========================================================================
void I2C_ReadNbyte(u8 addr, u8 *p, u8 number)   /*  WordAddress,First Data Address,Byte lenth   */
{
	EAXSFR();		/* MOVX A,@DPTR/MOVX @DPTR,Aָ��Ĳ�������Ϊ��չSFR(XSFR) */
	Start();                                //������ʼ����
	SendData(SLAW);                         //�����豸��ַ+д����
	RecvACK();
	SendData(addr);                         //���ʹ洢��ַ
	RecvACK();
	Start();                                //������ʼ����
	SendData(SLAR);                         //�����豸��ַ+������
	RecvACK();
	do
	{
		*p = RecvData();
		p++;
		if(number != 1) SendACK();          //send ACK
	}
	while(--number);
	SendNAK();                              //send no ACK	
	Stop();                                 //����ֹͣ����
	EAXRAM();		/* MOVX A,@DPTR/MOVX @DPTR,Aָ��Ĳ�������Ϊ��չRAM(XRAM) */
}
